using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Ajax;
using System.Web.Routing;
using System.Collections.Specialized;

using Microsoft.Practices.Unity;

using ERPStore.Services;
using ERPStore.Web.Html;
using ERPStore.Web.Extensions;

using CloudSoft.Extensions;

namespace ERPStore.Web.Controllers
{
	/// <summary>
	/// Controlleur du catalogue
	/// </summary>
	// [HandleError(View = "500")]
	public partial class CatalogController : StoreController
    {
		private static object m_lock = new object();

		public CatalogController(
			ICacheService cacheService,
			ICatalogService catalogService,
			IDocumentService documentService,
			ISalesService salesService, 
			IOffersService offerService,
			Services.IRewriterService rewriterService
			)
		{
			this.CacheService = cacheService;
			this.CatalogService = catalogService;
			this.DocumentService = documentService;
			this.SalesService = salesService;
			this.OfferService = offerService;
			this.RewriterService = rewriterService;
		}

		protected ICatalogService CatalogService { get; set; }
		protected ICacheService CacheService { get; set; }
		protected IDocumentService DocumentService { get; set; }
		protected ISalesService SalesService { get; set; }
		protected IOffersService OfferService { get; set; }
		protected Services.IRewriterService RewriterService { get; private set; }

        public ActionResult Index()
        {
            return View();
		}

		#region BySelection

		[ActionFilters.TrackerActionFilter]
		public ActionResult ProductListBySelection(string selectionName, int? page, int? pageSize)
		{
			if (!selectionName.IsNullOrTrimmedEmpty())
			{
				selectionName = selectionName.Trim().TrimEnd('/');
			}
			else
			{
				// return RedirectToAction("CategoryList");
				return RedirectToERPStoreRoute(ERPStore.Web.Routing.ERPStoreRoutes.HOME);
			}

			var selectionList = CatalogService.GetProductSelectionList();
			var selection = selectionList.FirstOrDefault(i => i.Name.Equals(selectionName, StringComparison.InvariantCultureIgnoreCase));

			if (selection == null)
			{
				return RedirectToERPStoreRoute(ERPStore.Web.Routing.ERPStoreRoutes.HOME);
			}

			var productSearch = CatalogService.CreateProductListFilter(this.HttpContext.GetWebContextParameterList());
			productSearch.SelectionId = selection.Id;

			var result = GetProductList(productSearch);

			result.SelectionId = selection.Id;
			ViewData.Model = result;

			EventPublisherService.PublishAsync(new Events.ProductListEvent(User, result, ERPStore.Models.ProductListType.Selection));

			return View("Selection");
		}

		public ActionResult ShowProductListBySelection(string viewName, string selectionName, int productCount)
		{
			var selectionList = CacheService["productSelectionList"] as IList<ERPStore.Models.EntitySelection>;
			if (selectionList == null)
			{
				selectionList = CatalogService.GetProductSelectionList();
				CacheService.Add("productSelectionList", selectionList, DateTime.Now.AddHours(1));
			}
			if (selectionList == null)
			{
				return new EmptyResult();
			}
			var selection = selectionList.SingleOrDefault(i => i.Name.Equals(selectionName, StringComparison.CurrentCultureIgnoreCase));
			if (selection == null)
			{
				return new EmptyResult();
			}

			var filter = new ERPStore.Models.ProductListFilter()
			{
				SelectionId = selection.Id,
			};
			int count = 0;
			var list = CatalogService.GetProductListBySearch(filter, 0, productCount, out count);

			SalesService.ApplyBestPrice(list, User.CurrentUser);

			return PartialView(viewName, list);
		}

		#endregion

		#region Profession

		#region Partial Views

		public ActionResult ShowProfessionList(string viewName)
		{
			var list = CatalogService.GetProfessionList();
			ViewData.Model = list;
			return PartialView(viewName);
		}

		#endregion

		#endregion

		public ERPStore.Models.ProductStockInfo GetProductStockInfoByCode(string productCode)
		{
			string key = string.Format("ProductDisponibility:{0}", productCode);
			var stockInfo = CacheService[key] as ERPStore.Models.ProductStockInfo;
			if (stockInfo == null)
			{
				try
				{
					stockInfo = CatalogService.GetProductStockInfo(productCode);
				}
				catch (Exception ex)
				{
					ex.Data.Add("productCode", productCode);
					Logger.Error(ex);
				}
				if (stockInfo == null)
				{
					stockInfo = new ERPStore.Models.ProductStockInfo();
					stockInfo.PhysicalStock = 0;
					stockInfo.ProvisionningDaysCount = -1;
				}
				CacheService.Add(key, stockInfo, DateTime.Now.AddMinutes(15));
			}
			return stockInfo;
		}

		#region Helpers


		ERPStore.Models.ProductList GetProductList(ERPStore.Models.ProductListFilter filter)
		{
			var pageId = GetPageId();
			var pageSize = GetPageSize();
			return GetProductList(filter, pageSize, pageId);
		}

		ERPStore.Models.ProductList GetProductList(ERPStore.Models.ProductListFilter filter, int pageSize)
		{
			var pageId = GetPageId();
			if (pageSize == -1)
			{
				pageSize = GetPageSize();
			}
			return GetProductList(filter, pageSize, pageId);
		}

		ERPStore.Models.ProductList GetProductList(ERPStore.Models.ProductListFilter filter, int pageSize, int pageId)
		{
			var count = 0;
			var productList = new List<ERPStore.Models.Product>();

			if (pageSize == -1)
			{
				pageSize = GetPageSize();
			}

			bool withTie = false;
			while (true)
			{
				IList<ERPStore.Models.Product> list = null;
				if (filter.CorporateId.HasValue || filter.UserId.HasValue)
				{
					list = CatalogService.GetProductListByCustomer(filter, pageId, pageSize, out count);
				}
				else
				{
					list = CatalogService.GetProductListBySearch(filter, pageId, pageSize, out count);
				}
					
				if (!list.IsNullOrEmpty())
				{
					productList.AddRange(list);
				}
				else
				{
					break;
				}
				var tie = count - (pageSize * (pageId + 1));
				if (pageId == 0
					&& tie < pageSize 
					&& tie > 0)
				{
					withTie = true;
					pageId++;
					continue;
				}
				break;
			}

			if (withTie)
			{
				pageId--;
				pageSize = count;
			}

			foreach (var item in productList)
			{
				OfferService.ApplyOffers(item, User.CurrentUser);
			}

			var result = new ERPStore.Models.ProductList(productList);
			var pageIndex = pageId + 1;

			result.ItemCount = count;
			result.PageIndex = pageIndex;
			result.PageSize = pageSize;

			result.ExtendedParameters = filter.ExtendedParameters;
			if (filter.ProductCategoryId.HasValue)
			{
				result.Category = filter.ProductCategory;
			}
			if (filter.BrandId.HasValue)
			{
				result.Brand = filter.Brand;
			}

			return result;
		}

        #endregion

    }
}